Better closure requirement propagation V2#154271
Better closure requirement propagation V2#154271LorrensP-2158466 wants to merge 1 commit intorust-lang:mainfrom
Conversation
Fix in question: We only propagate `T: 'ub` requirements when 'ub actually outlives the lower bounds of the type test. If none of the non-local upper bounds outlive it, then we propagate all of them.
|
|
||
| // For each region outlived by lower_bound find a non-local, | ||
| // universal region (it may be the same region) and add it to | ||
| // `ClosureOutlivesRequirement`. |
try_promote_type_test_subject + add a test.| // \ | ||
| // -> c | ||
| // / | ||
| // b |
There was a problem hiding this comment.
that's still odd and the test feels confusing/easier to fix than the one I wrote 🤔
In your test we have
'a: 'c
'b: 'c
T: 'a
We should clearly not propagate T: 'c and 'c: 'a. It's weird that we look at at universal_regions_outlived_by at all. Why are we not directly looking at the non_local_upper_bounds of lower_bound?
At least only look at the smallest such universal region
There was a problem hiding this comment.
We should clearly not propagate T: 'c and 'c: 'a
And that doesn't happen, I don't know what you mean with this.
It's weird that we look at at universal_regions_outlived_by at all. Why are we not directly looking at the non_local_upper_bounds of lower_bound
The function comment:
/// Once we've promoted T, we have to "promote" `'X` to some region
/// that is "external" to the closure. Generally speaking, a region
/// may be the union of some points in the closure body as well as
/// various free lifetimes. We can ignore the points in the closure
/// body: if the type T can be expressed in terms of external regions,
/// we know it outlives the points in the closure body. That
/// just leaves the free regions.
Otherwise I have no clue, dev-guide didn't give a reason. If I try to do non_local_upper_bounds of lower_bound the compiler panics:
thread 'rustc' (6493769) panicked at compiler/rustc_borrowck/src/type_check/free_region_relations.rs:113:9:
assertion failed: self.universal_regions.is_universal_region(fr0)
At least only look at the smallest such universal region
How is this possible?
There was a problem hiding this comment.
We should clearly not propagate
T: 'cand'c: 'a
on stable we propagate T: 'c as we separately require/know 'c: 'a, do we not? I guess we don't propagate 'c: 'a
There was a problem hiding this comment.
If I try to do
non_local_upper_boundsoflower_boundthe compiler panics:thread 'rustc' (6493769) panicked at compiler/rustc_borrowck/src/type_check/free_region_relations.rs:113:9: assertion failed: self.universal_regions.is_universal_region(fr0)At least only look at the smallest such universal region
How is this possible?
I guess we currently don't have a function to just do that right away, unsure.
We could call universal_regions_outlived_by and then manually filter the universals to ones which are not outlived by any other of the returned regions.
There's ReverseSccGraph.upper_bounds which seems useful?
How is this possible?
I guess the core answer here is
- we have a way to get all universal regions which are required
universal_regions_outlived_by - and then have a way to test whether
universal_regionsoutlive each other
so this is definitely possible, worst case we have to reimpl it
Fixes #154267
Unblocks #151510.
We only propagate
T: 'ubrequirements when'ubactually outlives the lower bound of the type test. If none of the non-local upper bounds outlive the lower bound, then we propagate all of them.r? @lcnr